from flask import Flask, render_template, request, jsonify, send_file
import os
from datetime import datetime
import tempfile
from playwright.sync_api import sync_playwright
import traceback

app = Flask(__name__)

# 配置
app.config['UPLOAD_FOLDER'] = 'generated_cards'
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)

@app.route('/')
def index():
    """主页 - 提供HTML粘贴和选择器输入的界面"""
    default_html_content = ""
    try:
        # 从文件读取默认的HTML内容
        with open('deepseek_html_20250605_fb6f8f.html', 'r', encoding='utf-8') as f:
            default_html_content = f.read()
    except FileNotFoundError:
        print("警告: 未找到默认HTML文件 'deepseek_html_20250605_fb6f8f.html'。文本区域将为空。")

    return render_template('card_generator.html', default_html=default_html_content)

def generate_image_with_playwright(html_filepath: str, output_path: str, selector: str, add_rounded_corners: bool = True):
    """
    使用 Playwright (Python) 从本地 HTML 文件生成截图。
    """
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True, args=['--no-sandbox', '--disable-setuid-sandbox'])
        page = browser.new_page()

        try:
            page.set_viewport_size({"width": 450, "height": 950})
            
            # 使用 file:// 协议加载本地文件
            absolute_html_path = os.path.abspath(html_filepath)
            page.goto(f'file://{absolute_html_path}', wait_until='networkidle')

            # 等待字体和样式加载
            page.wait_for_timeout(1500)
            page.evaluate("document.fonts.ready")

            # 注入通用样式，确保背景透明
            page.add_style_tag(content="""
                body { background: transparent !important; margin: 0 !important; padding: 0 !important; }
                *, *::before, *::after {
                    animation-duration: 0s !important;
                    animation-delay: 0s !important;
                    transition-duration: 0s !important;
                    transition-delay: 0s !important;
                }
            """)
            page.wait_for_timeout(500)

            target_element = page.locator(selector).first
            if not target_element.is_visible():
                raise Exception(f"Element with selector '{selector}' not found or not visible.")

            # 根据选项决定是否注入圆角样式
            if add_rounded_corners:
                page.add_style_tag(content=f"""
                    {selector} {{
                        clip-path: inset(0 round 20px) !important;
                        overflow: hidden !important;
                    }}
                """)
                page.wait_for_timeout(200)

            # 截图
            target_element.screenshot(
                path=output_path,
                omit_background=True,
                animations="disabled"
            )
        finally:
            browser.close()

@app.route('/health')
def health_check():
    """检查Playwright环境是否正常的健康检查接口"""
    try:
        with sync_playwright() as p:
            # 尝试启动一个浏览器来验证安装是否完整
            browser = p.chromium.launch()
            browser.close()
        return jsonify({'status': 'ok', 'playwright_check': 'success'}), 200
    except Exception as e:
        print(f"健康检查失败: {e}")
        traceback.print_exc()
        return jsonify({'status': 'error', 'playwright_check': 'failed', 'details': str(e)}), 500

def suggest_selector_with_playwright(html_filepath: str) -> str:
    """
    使用 Playwright (Python) 从本地 HTML 文件分析并建议一个主元素的选择器。
    """
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True, args=['--no-sandbox', '--disable-setuid-sandbox'])
        page = browser.new_page()
        try:
            absolute_html_path = os.path.abspath(html_filepath)
            page.goto(f'file://{absolute_html_path}', wait_until='domcontentloaded')

            # 注入脚本来寻找最佳选择器
            suggested_selector = page.evaluate("""() => {
                // 常见的容器ID或类名
                const commonSelectors = [
                    '#card', '.card', 
                    '#container', '.container', 
                    '#main', '.main', 
                    '#root', '.root', 
                    '#app', '.app',
                    '[class*="card"]', '[class*="container"]'
                ];

                for (const selector of commonSelectors) {
                    if (document.querySelector(selector)) {
                        return selector;
                    }
                }
                
                // 备用逻辑：找到body的第一个有ID或class的直接子元素
                const directChildren = document.body.children;
                if (directChildren.length > 0) {
                    for(const child of directChildren) {
                        if (child.id) {
                            return '#' + child.id;
                        }
                        if (child.className && typeof child.className === 'string') {
                            const classes = child.className.split(' ').filter(c => c);
                            if (classes.length > 0) {
                                return '.' + classes[0];
                            }
                        }
                    }
                }

                // 如果只有一个子元素，就用它
                if (directChildren.length === 1) {
                   const child = directChildren[0];
                   let selector = child.tagName.toLowerCase();
                   if (child.id) {
                       selector += '#' + child.id;
                   } else if (child.className && typeof child.className === 'string') {
                       const classes = child.className.split(' ').filter(c => c);
                       if (classes.length > 0) {
                           selector += '.' + classes.join('.');
                       }
                   }
                   return selector;
                }

                return 'body'; // 最终的备用方案
            }""")
            return suggested_selector
        finally:
            browser.close()

@app.route('/api/suggest_selector', methods=['POST'])
def suggest_selector():
    """接收HTML，分析并返回建议的CSS选择器"""
    temp_html_filepath = None
    try:
        data = request.json
        html_content = data.get('html_content')
        if not html_content:
            return jsonify({'success': False, 'error': '缺少HTML内容'}), 400

        with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.html', encoding='utf-8', dir=app.config['UPLOAD_FOLDER']) as tmp_html_file:
            tmp_html_file.write(html_content)
            temp_html_filepath = tmp_html_file.name

        selector = suggest_selector_with_playwright(temp_html_filepath)
        
        return jsonify({'success': True, 'selector': selector})

    except Exception as e:
        print(f"分析选择器时发生错误: {e}")
        traceback.print_exc()
        return jsonify({'success': False, 'error': '分析选择器失败', 'details': str(e)}), 500
    finally:
        if temp_html_filepath and os.path.exists(temp_html_filepath):
            try:
                os.remove(temp_html_filepath)
            except OSError as e_clean_html:
                print(f"清理临时HTML文件 {temp_html_filepath} 时出错: {e_clean_html}")

@app.route('/api/process_html_and_capture', methods=['POST'])
def process_html_and_capture():
    """接收HTML和选择器，使用Python Playwright生成截图并返回图片"""
    temp_html_filepath = None
    output_image_path = None

    try:
        data = request.json
        html_content = data.get('html_content')
        selector = data.get('selector')
        add_rounded_corners = data.get('add_rounded_corners', True) # 获取选项，默认为True

        if not html_content or not selector:
            return jsonify({'success': False, 'error': '缺少HTML内容或CSS选择器'}), 400

        with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.html', encoding='utf-8', dir=app.config['UPLOAD_FOLDER']) as tmp_html_file:
            tmp_html_file.write(html_content)
            temp_html_filepath = tmp_html_file.name
        
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S_%f')
        output_image_filename = f'capture_{timestamp}.png'
        output_image_path = os.path.join(app.config['UPLOAD_FOLDER'], output_image_filename)
        
        # 使用新的Python Playwright函数，并传递圆角选项
        generate_image_with_playwright(temp_html_filepath, output_image_path, selector, add_rounded_corners)

        if os.path.exists(output_image_path):
            return send_file(
                output_image_path,
                as_attachment=True,
                download_name='captured_image.png',
                mimetype='image/png'
            )
        else:
            print(f"错误: 图片文件声称已生成但未找到于 {output_image_path}")
            return jsonify({'success': False, 'error': '图片文件生成后未找到'}), 500
            
    except Exception as e:
        print(f"处理截图请求时发生意外错误: {e}")
        traceback.print_exc()
        # 返回更详细的错误给前端
        return jsonify({'success': False, 'error': 'Playwright截图失败', 'details': str(e)}), 500
    finally:
        # 清理临时文件
        if temp_html_filepath and os.path.exists(temp_html_filepath):
            try:
                os.remove(temp_html_filepath)
            except OSError as e_clean_html:
                print(f"清理临时HTML文件 {temp_html_filepath} 时出错: {e_clean_html}")
        
        if output_image_path and os.path.exists(output_image_path):
            try:
                os.remove(output_image_path)
            except OSError as e_clean_img:
                print(f"清理生成的图片 {output_image_path} 时出错: {e_clean_img}")

if __name__ == '__main__':
    os.makedirs('templates', exist_ok=True)
    # 第一次运行时，需要安装浏览器依赖
    # 在命令行中运行: playwright install
    app.run(debug=True, host='0.0.0.0', port=8036)